using System.Net.Http.Json;
using APITransLib.Contracts;

namespace ChatWithMultAI.Services;

public interface IChatService
{
    Task<MessageDto> SendToUserAsync(string fromUserId, string toUserId, string content, CancellationToken ct = default);
    Task<MessageDto> SendToGroupAsync(string fromUserId, string groupId, string content, CancellationToken ct = default);
    Task<GroupDto> CreateGroupAsync(string name, IEnumerable<string> memberIds, CancellationToken ct = default);
    Task AddUsersToGroupAsync(string groupId, IEnumerable<string> userIds, CancellationToken ct = default);
    Task<IReadOnlyList<MessageDto>> GetUserMessagesAsync(string userId, int skip = 0, int take = 50, CancellationToken ct = default);
}

public class ChatService(HttpClient http) : IChatService
{
    public async Task<MessageDto> SendToUserAsync(string fromUserId, string toUserId, string content, CancellationToken ct = default)
    {
        var req = new SendMessageRequest { ToUserId = toUserId, ToGroupId = null, Kind = MessageKind.Text, Content = content };
        var res = await http.PostAsJsonAsync($"api/messages/send/{fromUserId}", req, ct);
        res.EnsureSuccessStatusCode();
        var body = await res.Content.ReadFromJsonAsync<SendMessageResponse>(cancellationToken: ct);
        if (body?.Message is null) throw new InvalidOperationException("send failed");
        return body.Message;
    }

    public async Task<MessageDto> SendToGroupAsync(string fromUserId, string groupId, string content, CancellationToken ct = default)
    {
        var req = new SendMessageRequest { ToUserId = null, ToGroupId = groupId, Kind = MessageKind.Text, Content = content };
        var res = await http.PostAsJsonAsync($"api/messages/send/{fromUserId}", req, ct);
        res.EnsureSuccessStatusCode();
        var body = await res.Content.ReadFromJsonAsync<SendMessageResponse>(cancellationToken: ct);
        if (body?.Message is null) throw new InvalidOperationException("send failed");
        return body.Message;
    }

    public async Task<GroupDto> CreateGroupAsync(string name, IEnumerable<string> memberIds, CancellationToken ct = default)
    {
        var req = new CreateGroupRequest { Name = name, MemberUserIds = memberIds.ToList() };
        var res = await http.PostAsJsonAsync("api/groups", req, ct);
        res.EnsureSuccessStatusCode();
        var body = await res.Content.ReadFromJsonAsync<CreateGroupResponse>(cancellationToken: ct);
        if (body?.Group is null) throw new InvalidOperationException("create group failed");
        return body.Group;
    }

    public async Task AddUsersToGroupAsync(string groupId, IEnumerable<string> userIds, CancellationToken ct = default)
    {
        var req = new AddUsersToGroupRequest { GroupId = groupId, UserIds = userIds.ToList() };
        var res = await http.PostAsJsonAsync("api/groups/add-users", req, ct);
        res.EnsureSuccessStatusCode();
    }

    public async Task<IReadOnlyList<MessageDto>> GetUserMessagesAsync(string userId, int skip = 0, int take = 50, CancellationToken ct = default)
    {
        var res = await http.GetAsync($"api/messages/user/{userId}?skip={skip}&take={take}", ct);
        res.EnsureSuccessStatusCode();
        var body = await res.Content.ReadFromJsonAsync<PagedResponse<MessageDto>>(cancellationToken: ct);
        return body?.Items?.ToList() ?? new List<MessageDto>();
    }
}
